package com.baigt.jvm;

/**
 * 类功能描述:
 *      使用Holder的好处是什么？
 *      Singleton的实例，Singleton实例的创建过程在Java程序编译时期收集至< clinit>()方法中，
 *      该方法又是同步方法，同步方法可以保证内存的可见性、JVM指令的顺序性和原子性、
 *      Holder方式的单例设计是最好的设计之一，也是目前使用比较广的设计之一
 * @author baigt
 * @version V1.0
 * @since 2019-11-06 16:51
 */
public final class Singleton {
    // 实例变量
    private byte[] data =new byte[1024];
    // 代码01
//    private   static Singleton data2 =new Singleton();
    static {
        System.out.println("Singleton");
    }
    private Singleton(){
        System.out.println("Singleton init");
    }
    // 静态内部类中来进行Singleton实例，并且可以被初始化
    private static class Holder{
        // 这行代码 放在Singleton的成员变量中和放在里有什么不同？
        // Class.forName("com.ricky.jvm.Singleton");   在使用Holder方法时，"Singleton init" 不会打印，
        // 使用代码01处则 则在loadClass时就会打印 "Singleton init"
        // 通过Holder的方法达到了延迟加载的目的，又保证了线程的安全性
        // 说明 类加载过程，jvm会加载和初始化 static属性的变量
        //  如果使用“代码01”处则会直接创建Singleton对象，此时  实例变量 data 也会直接创建在堆空间中
        //  如果采用 Holder的方法，则会延迟加载创建对象实例，在真正使用的时候创建对象(含data对象)
        // 注意 cinit 和init的区别
        private static Singleton instance=new Singleton();
    }
    // 调用此方法，实际上是调用Holder的静态变量
    public static Singleton getInstance(){
        return Holder.instance;
    }
}
